#include <gtest/gtest.h>
#include "Thread/ThreadGroup.h"
#include <atomic>
#include <chrono>

using namespace toolkit;
using namespace std::chrono_literals;

// 测试创建线程和线程数量
TEST(ThreadGroupTest, CreateAndSize) {
    ThreadGroup group;
    
    // 初始线程数应为0
    EXPECT_EQ(group.size(), 0);
    
    // 创建3个线程
    std::atomic<int> counter{0};
    
    auto thread_id1 = group.createThread([&counter]() {
        counter++;
        std::this_thread::sleep_for(100ms);
    });
    
    auto thread_id2 = group.createThread([&counter]() {
        counter++;
        std::this_thread::sleep_for(100ms);
    });
    
    auto thread_id3 = group.createThread([&counter]() {
        counter++;
        std::this_thread::sleep_for(100ms);
    });
    
    // 线程数应为3
    EXPECT_EQ(group.size(), 3);
    
    // 等待所有线程完成
    group.joinAll();
    
    // 线程数应为0
    EXPECT_EQ(group.size(), 0);
    
    // 计数器应为3
    EXPECT_EQ(counter, 3);
}

// 测试线程移除功能
TEST(ThreadGroupTest, RemoveThread) {
    ThreadGroup group;
    
    std::atomic<bool> thread1_running{false};
    std::atomic<bool> thread2_running{false};
    std::atomic<bool> can_exit{false};
    
    // 创建两个长时间运行的线程
    auto thread_id1 = group.createThread([&]() {
        thread1_running = true;
        while (!can_exit) {
            std::this_thread::sleep_for(10ms);
        }
    });
    
    auto thread_id2 = group.createThread([&]() {
        thread2_running = true;
        while (!can_exit) {
            std::this_thread::sleep_for(10ms);
        }
    });
    
    // 等待线程启动
    while (!thread1_running || !thread2_running) {
        std::this_thread::sleep_for(10ms);
    }
    
    // 线程数应为2
    EXPECT_EQ(group.size(), 2);
    
    // 移除第一个线程
    can_exit = true; // 允许线程退出
    bool removed = group.removeThread(thread_id1);
    EXPECT_TRUE(removed);
    
    // 线程数应为1
    EXPECT_EQ(group.size(), 1);
    
    // 尝试移除不存在的线程
    removed = group.removeThread(std::thread::id());
    EXPECT_FALSE(removed);
    
    // 线程数仍为1
    EXPECT_EQ(group.size(), 1);
}

// 测试hasThread和isCurrentThreadIn功能
TEST(ThreadGroupTest, ThreadMembership) {
    ThreadGroup group;
    
    std::atomic<bool> thread_checked{false};
    std::atomic<bool> in_group{false};
    std::atomic<bool> can_exit{false};
    
    // 创建一个线程，检查它是否在组中
    auto thread_id = group.createThread([&]() {
        in_group = group.isCurrentThreadIn();
        thread_checked = true;
        
        while (!can_exit) {
            std::this_thread::sleep_for(10ms);
        }
    });
    
    // 等待线程检查完成
    while (!thread_checked) {
        std::this_thread::sleep_for(10ms);
    }
    
    // 线程应该在组中
    EXPECT_TRUE(in_group);
    
    // 当前测试线程不应该在组中
    EXPECT_FALSE(group.isCurrentThreadIn());
    
    // 检查指定线程是否在组中
    EXPECT_TRUE(group.hasThread(thread_id));
    EXPECT_FALSE(group.hasThread(std::thread::id()));
    
    // 清理
    can_exit = true;
    group.joinAll();
}

// 测试析构函数是否正确等待所有线程
TEST(ThreadGroupTest, DestructorJoinsThreads) {
    std::atomic<int> counter{0};
    
    {
        ThreadGroup group;
        
        // 创建5个线程，每个线程睡眠一段时间后增加计数器
        for (int i = 0; i < 5; i++) {
            group.createThread([&counter, i]() {
                std::this_thread::sleep_for(std::chrono::milliseconds(50 * (i + 1)));
                counter++;
            });
        }
        
        // 离开作用域，ThreadGroup析构函数应该等待所有线程
    }
    
    // 所有线程应该已完成，计数器应为5
    EXPECT_EQ(counter, 5);
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}